home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Scripting / Source / StevesFlowControl.cpp < prev    next >
Encoding:
Text File  |  1995-09-10  |  13.9 KB  |  185 lines  |  [TEXT/MPCC]

  1. /*---------------------------------------------------------------
  2.     Copyright 1995, Steve Israelson
  3.     
  4.     I own this code.  You are free to use this code in any software
  5.     you want.  You may not sell this source code at all, you can 
  6.     sell your product though.  If you want to include this code
  7.     in any code collection (CD-Roms etc) this is OK as long as
  8.     I get a complimentary copy.
  9.             Steve.
  10.     
  11.     Uses a parser to parse one line of a script.  Handles all the
  12.     needed flow control constructs.  The caller must be able
  13.     to jump to any line in the script specified.
  14.     
  15.     The flow control works as follows:
  16.  
  17.     If (expr)    // this evaluates the expr and executes code if true, until and Endif or Else
  18.     Else        // if the expr is false in the If() statement, then the code between the Else and Endif executes
  19.     Endif        // terminates the If() statement
  20.     While (expr)// while the expr is true, the code between the While() and EndWhile executes
  21.     EndWhile    // loops to the previous while statement
  22.     Repeat        // starts a repeat loop.  Code executes until the Until() statement is true
  23.     Until(expr)    // loops to the previous Repeat statement unless the expr is true
  24.     Gosub label // Code execution continues at the matching Subroutine statement
  25.     Subroutine label    // Indicates the start of a subroutine and its label.  Code only executes in response to Gosub
  26.     EndSub        // Execution resumes on the line following the Gosub that called us.
  27.     
  28.     And the expressions (expr above):
  29.     num < num
  30.     num <= num
  31.     num = num
  32.     num != num
  33.     num >= num
  34.     num > num
  35.     Where num can be anything your numerical parser can parse into an integer.
  36.  
  37. ---------------------------------------------------------------*/
  38. #include "StevesFlowControl.h"
  39. #include <String.h>
  40.  
  41. /*---------------------------------------------------------------
  42.     Build our two parsers.
  43.     Pass in a pointer to your numerical evaluation function.
  44.     Pass in any data you want for itsData.  It will be passed
  45.     to your numerical evaluator.
  46. ---------------------------------------------------------------*/
  47. MyFlowControl::MyFlowControl(numericalmp;
  48.         }
  49.     theParams.RemoveItemsAt(1000, 1);
  50.  
  51.     if (token > kToken_Error_Last)    // only return errors and stuff
  52.         token = kToken_Ignore;
  53.     return token;    
  54.     }
  55.  
  56. /*---------------------------------------------------------------
  57.     Find and return a subroutine entry in our list.
  58.     Checks each one and returns the correct one or nil.
  59. ---------------------------------------------------------------*/
  60. subroutineEntry *MyFlowControl::FindSubroutine(char *text)
  61.     {
  62.     for (int x = 1; x <= Subroutines.GetCount(); ++x)
  63.         {
  64.         subroutineEntry    *theEntry;
  65.         if (Subroutines.FetchItemAt(x, &theEntry))
  66.             if (!strcmp(text, theEntry->itsName))
  67.                 return theEntry;
  68.         }
  69.     return nil;
  70.     }
  71.  
  72. /*---------------------------------------------------------------
  73.     Add a number to the param list.  Should use atoi(), but where
  74.     is it?
  75. ---------------------------------------------------------------*/
  76. void MyFlowControl::AddLongParam(LList *theParams, long theNum)
  77.     {
  78.     char    *theStr = NewPtr(64);
  79.     NumToString(theNum, (StringPtr)theStr);
  80.     PtoCstr((StringPtr)theStr);
  81.     theParams->InsertItemsAt(1, 1, &theStr);
  82.     }
  83.  
  84. /*---------------------------------------------------------------
  85.     Add an item to the stack.  The condition state is for things
  86.     like if statements.  Its true if the condition is true.
  87.     canExecute is false if the code can not execute any way, usually
  88.     because we are inside a nested if that is not executing.
  89. ---------------------------------------------------------------*/
  90. void MyFlowControl::PushOntoStack(long token, long theLineNum, char *theLabel, 
  91.             Boolean conditionState, Boolean canExecute, Boolean isSearching)
  92.     {
  93.     stackEntry        *newEntry = (stackEntry*)NewPtrClear(sizeof(stackEntry));
  94.     if (newEntry)
  95.         {
  96.         newEntry->token = token;
  97.         newEntry->itsLineNum = theLineNum;
  98.         newEntry->theLabel = theLabel;
  99.         newEntry->isExecuting = canExecute;
  100.         newEntry->isSearching = isSearching;
  101.         newEntry->conditionState = conditionState;
  102.         
  103.         Stack.InsertItemsAt(1, arrayIndex_Last, &newEntry);    
  104.         }
  105.     else    // error?
  106.         if (theLabel)
  107.             DisposePtr(theLabel);    // clean up
  108.     }
  109.  
  110. /*---------------------------------------------------------------
  111.     Toast the top item on the stack
  112. ---------------------------------------------------------------*/
  113. void MyFlowControl::PopStack(void)
  114.     {
  115.     stackEntry        *oldEntry;
  116.     if (Stack.FetchItemAt(arrayIndex_Last, &oldEntry))
  117.         {
  118.         Stack.Remove(&oldEntry);
  119.         if (oldEntry->theLabel)
  120.             DisposePtr(oldEntry->theLabel);
  121.         DisposePtr((Ptr)oldEntry);
  122.         }
  123.     }
  124.  
  125. /*---------------------------------------------------------------
  126.     Evaluate the expression and return its truth.
  127.     Calls your code to find the numerical value of
  128.     a numerical expression, which could include variables.
  129. ---------------------------------------------------------------*/
  130. Boolean MyFlowControl::EvalExpression(char *theExpression)
  131.     {
  132.     Boolean        returnValue = false;
  133.     long        token;
  134.     LList        theParams;
  135.     char        *paramater1, *paramater2;
  136.     long        n1, n2;
  137.     
  138.     // parse the given line and get the token
  139.     token = expressions.Parse(theExpression, &theParams);
  140.     
  141.     // get the two parameters (should always be two too
  142.        theParams.FetchItemAt(1, ¶mater1);
  143.        theParams.FetchItemAt(2, ¶mater2);
  144.     
  145.     n1 = (*evalNumber)(paramater1, theUserData);
  146.     n2 = (*evalNumber)(paramater2, theUserData);
  147.  
  148.     switch (token)
  149.         {
  150.         default:    // expression error
  151.             break;
  152.         case kToken_Equal:
  153.             returnValue = (n1 == n2);
  154.             break;
  155.         case kToken_GreaterThan:         
  156.             returnValue = (n1 > n2);
  157.             break;
  158.         case kToken_LessThan:                 
  159.             returnValue = (n1 < n2);
  160.             break;
  161.         case kToken_NotEqual:                 
  162.             returnValue = (n1 != n2);
  163.             break;
  164.         case kToken_GreaterThanOrEqual:                 
  165.             returnValue = (n1 >= n2);
  166.             break;
  167.         case kToken_LessThanOrEqual:                 
  168.             returnValue = (n1 <= n2);
  169.             break;
  170.         }
  171.     
  172.     // toast all the params
  173.     for (int i = 1; i < theParams.GetCount(); ++i)
  174.         {
  175.         char *temp;
  176.         if (theParams.FetchItemAt(i, &temp))
  177.             delete temp;
  178.         }
  179.     theParams.RemoveItemsAt(1000, 1);
  180.     return returnValue;  
  181.     }
  182.  
  183.  
  184.   
  185.